package com.kakarote.hrm.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.constant.OrgConstant;
import com.kakarote.core.common.enums.DataAuthEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.LocalDateTimeUtil;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.common.EmployeeHolder;
import com.kakarote.hrm.constant.*;
import com.kakarote.hrm.entity.BO.QueryDeptListBO;
import com.kakarote.hrm.entity.BO.QueryEmployeePageListBO;
import com.kakarote.hrm.entity.BO.QueryWorkbenchEmployeeListBO;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.hrm.entity.VO.*;
import com.kakarote.hrm.mapper.HrmDeptMapper;
import com.kakarote.hrm.mapper.HrmEmployeeMapper;
import com.kakarote.hrm.service.*;
import com.kakarote.hrm.utils.EmployeeUtil;
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 绩效考核 服务实现类
 * </p>
 *
 * @author huangmingbo
 * @since 2020-05-12
 */
@Service
public class WxMiniEmpServiceServiceImpl extends BaseServiceImpl<HrmDeptMapper, HrmDept> implements IWxMiniEmpService {

    @Autowired
    private IHrmEmployeeService employeeService;

    @Autowired
    private HrmEmployeeMapper employeeMapper;

    @Autowired
    private IHrmDeptService deptService;

    @Autowired
    private HrmDeptMapper deptMapper;

    @Autowired
    private IHrmEmployeeDataService employeeDataService;

    @Autowired
    private IHrmEmployeeSpecialWorkerService employeeSpecialWorkerService;

    @Autowired
    private IHrmEmployeeDataService hrmEmployeeData;

    @Autowired
    private IHrmEmployeeTechnicalService employeeTechnicalService;

    @Autowired
    private IHrmEmployeeEncryptFieldService employeeEncryptFieldService;

    @Autowired
    private AdminService adminService;

    @Autowired
    private EmployeeUtil employeeUtil;

    @Override
    public List<EmployeeMiniInfo> getEmpList(EmployeeMiniInfo info) {
        List<EmployeeMiniInfo> list = new ArrayList<>();
        if (StrUtil.isNotEmpty(info.getName())) {
            List<Long> empIds = employeeService.lambdaQuery().select(HrmEmployee::getEmployeeId).eq(HrmEmployee::getIsDel, 0).list()
                    .stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
            QueryEmployeePageListBO employeePageListBO = new QueryEmployeePageListBO();
            BeanUtils.copyProperties(info, employeePageListBO);
            employeePageListBO.setEmployeeName(info.getName());
            employeePageListBO.setPage(info.getPage());
            employeePageListBO.setLimit(info.getLimit());
            employeePageListBO.setPageType(1);
            BasePage<Map<String, Object>> mapBasePage = employeeService.fullTextSearch(employeePageListBO, empIds);
            List<Map<String, Object>> empListMap = mapBasePage.getList();
            for (Map<String, Object> map : empListMap) {
                EmployeeMiniInfo employeeMiniInfo = new EmployeeMiniInfo();
                employeeMiniInfo.setEeId(Long.parseLong(map.get("employeeId").toString()));
                employeeMiniInfo.setName(Optional.ofNullable(map.get("employeeName")).orElse("").toString());
                employeeMiniInfo.setPhone(Optional.ofNullable(map.get("mobile")).orElse("").toString());
                employeeMiniInfo.setOrgId(map.get("orgId") == null ? null : Long.parseLong(map.get("orgId").toString()));
                employeeMiniInfo.setDeptId(map.get("deptId") == null ? null :Long.parseLong(map.get("deptId").toString()));
                employeeMiniInfo.setPost(map.get("jobTitle") == null ? "" :map.get("jobTitle").toString());
                employeeMiniInfo.setEntryTime(map.get("companyAgeStartTime") == null ? null : LocalDateTimeUtil.parse(map.get("companyAgeStartTime").toString(), "yyyy-MM-dd"));
                list.add(employeeMiniInfo);
            }
        } else {
            info.setPage((info.getPage() - 1) * info.getLimit());
            list = employeeService.getEmpListByName(info);
        }
        for (EmployeeMiniInfo emp : list) {
            List<EmployeeMiniInfoDetail> detailList = new ArrayList<>();
            EmployeeMiniInfoDetail detail = new EmployeeMiniInfoDetail();
            detail.setJobTitle(emp.getPost());
            detail.setJobStartTime(emp.getEntryTime());
            HrmDept org = deptService.lambdaQuery().select(HrmDept::getName).eq(HrmDept::getDeptId, emp.getOrgId()).one();
            HrmDept dept = deptService.lambdaQuery().select(HrmDept::getName).eq(HrmDept::getDeptId, emp.getDeptId()).one();
            if (dept != null) {
                detail.setDeptName(dept.getName());
            }
            if (org != null) {
                detail.setOrgName(org.getName());
            }
            detailList.add(detail);
            emp.setOrgInfo(detailList);
        }
        return list;
    }

    @Override
    public Result getEmpListByOrg(Long deptId) {
        List<EmployeeMini> employeeList = employeeService.selectEmployeeListByDeptId(deptId);
        if (employeeList != null && !employeeList.isEmpty()) {
            List<Long> empIdList = employeeList.stream().map(EmployeeMini::getId).collect(Collectors.toList());
            List<HrmEmployeeData> empDataList = hrmEmployeeData.lambdaQuery().select(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldName, HrmEmployeeData::getFieldValue).in(HrmEmployeeData::getEmployeeId, empIdList).list();
            List<String> dataFileNameList = Arrays.asList("highest_tech_level", "job_level", "job_title");
            Map<Long, Map<String, String>> empDataMap = empDataList.stream().filter(data -> data.getEmployeeId() != null
                            && StringUtils.isNotEmpty(data.getFieldName())
                            && StringUtils.isNotEmpty(data.getFieldValue())
                            && dataFileNameList.contains(data.getFieldName()))
                    .collect(Collectors.groupingBy(HrmEmployeeData::getEmployeeId, Collectors.toMap(HrmEmployeeData::getFieldName, HrmEmployeeData::getFieldValue, (v1, v2) -> v1)));
            for (EmployeeMini emp : employeeList) {
                if (empDataMap.containsKey(emp.getId())) {
                    Map<String, String> nameValueMap = empDataMap.get(emp.getId());
                    // 最高职称级别
                    if (nameValueMap.containsKey("highest_tech_level")) {
                        emp.setHighestTechLevel(nameValueMap.get("highest_tech_level"));
                    }
                    // 职位层级
                    if (nameValueMap.containsKey("job_level")) {
                        emp.setJobLevel(nameValueMap.get("job_level"));
                    }
                    // 职务
                    if (nameValueMap.containsKey("job_title")) {
                        emp.setJobTitle(nameValueMap.get("job_title"));
                    }
                }
            }
        }

        HrmDept one = deptService.lambdaQuery().eq(HrmDept::getDeptId, deptId).one();
        JSONObject data = new JSONObject();
        data.put("org", one);
        data.put("data", employeeList);
        data.put("msg", "操作成功");
        return Result.ok(data);
    }

    @Override
    public Result getDeptChild(Long deptId) {
        if (deptId == 0) {
            HrmDept parent = deptService.lambdaQuery().eq(HrmDept::getParentId, deptId).one();
            deptId = parent.getDeptId();
        }
        // 员工  包含年龄，性别，最高学历，部门id
//        List<EmployeeMini> employeeList = employeeService.selectEmployeeOfDeptIdList();


//        List<HrmEmployeeData> orgByEmpIdList = employeeDataService.lambdaQuery()
//                .eq(HrmEmployeeData::getFieldName, "org")
//                .list();
//        Map<Long, String> orgByEmpIdMap = orgByEmpIdList.stream()
//                .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()))
//                .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
//                .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
//
//
//        List<HrmEmployeeData> deptByEmpIdList = employeeDataService.lambdaQuery()
//                .eq(HrmEmployeeData::getFieldName, "dept")
//                .list();
//
//        Map<Long, String> deptByEmpIdMap = deptByEmpIdList.stream()
//                .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()))
//                .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
//                .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
//
//
//        for (EmployeeMini mini : employeeList) {
//            if (orgByEmpIdMap.containsKey(mini.getId())) {
//                mini.setOrgId(Long.valueOf(orgByEmpIdMap.get(mini.getId())));
//            }
//            if (deptByEmpIdMap.containsKey(mini.getId())) {
//                mini.setDeptId(Long.valueOf(deptByEmpIdMap.get(mini.getId())));
//            }
//        }

        // 所有机构信息
        List<HrmDept> allDeptList = deptService.lambdaQuery().list();
        List<Integer> dataAuthTypeList = adminService.queryDataTypeList(UserUtil.getUserId(), MenuIdConstant.DEPT_MENU_ID).getData();
        if (EmployeeHolder.isHrmAdmin() || dataAuthTypeList.contains(DataAuthEnum.ALL.getValue())) {
        }else {
            Set<Long> deptIds = employeeUtil.queryDataAuthDeptId(dataAuthTypeList, MenuIdConstant.DEPT_MENU_ID);
            deptIds.add(-1L);
            allDeptList = allDeptList.stream().filter(dept -> deptIds.contains(dept.getDeptId())).collect(Collectors.toList());
        }

        // 所有子集机构
        Map<Long, List<HrmDept>> allDeptMap = allDeptList.stream().collect(Collectors.groupingBy(HrmDept::getParentId));

        // 当前机构
        HrmDept one = deptService.lambdaQuery().eq(HrmDept::getDeptId, deptId).one();

        JSONObject data = new JSONObject();

        List<HrmDept> deptEmployeeVOS = allDeptMap.get(deptId);
        if (CollectionUtils.isNotEmpty(deptEmployeeVOS)) {
            Map<Integer, List<HrmDept>> collect = deptEmployeeVOS.stream().filter(dept -> dept.getDeptType() != null).collect(Collectors.groupingBy(HrmDept::getDeptType));
            Iterator<Map.Entry<Integer, List<HrmDept>>> iterator = collect.entrySet().iterator();
            List<DeptVO> deptList = deptMapper.queryList(new QueryDeptListBO());
            List<DeptVO> deptTotalTree = deptService.createDeptTotalTree(0L, deptList);
            while (iterator.hasNext()) {
                Map.Entry<Integer, List<HrmDept>> next = iterator.next();
                Integer key = next.getKey();
                List<HrmDept> value = next.getValue();
                List<DeptEmployeeVO> voList = new ArrayList<>();
                value = value.stream().sorted(Comparator.comparing(HrmDept::getSortId, Comparator.nullsLast(Long::compareTo)).thenComparing(HrmDept::getDeptId)).collect(Collectors.toList());
                List<Long> deptIds = value.stream().map(HrmDept::getDeptId).collect(Collectors.toList());
                HashMap<Long, Integer> countMap = new HashMap<>();
                getDeptEmployeecurrentNum(deptIds, deptTotalTree, countMap);
                for (int i = 0; i < value.size(); i++) {

                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    HrmDept deptEmployeeVO = value.get(i);
//                    List<HrmDept> deptByDeptId = this.getDeptByDeptId(deptEmployeeVO.getDeptId(), allDeptMap);
//                    List<Long> deptIdList = deptByDeptId.stream().map(dept -> dept.getDeptId()).collect(Collectors.toList());
//                    deptIdList.add(deptEmployeeVO.getDeptId());
//                    List<EmployeeMini> empChildList = employeeList.stream().filter(emp -> deptIdList.contains(emp.getDeptId()) || deptIdList.contains(emp.getOrgId())).collect(Collectors.toList());

                    BeanUtils.copyProperties(deptEmployeeVO, vo);
                    vo.setCurrentNum(Optional.ofNullable(countMap.get(deptEmployeeVO.getDeptId())).orElse(0));
                    vo.setName(deptEmployeeVO.getName());
                    voList.add(vo);
                }
                if (key == 1) {
                    data.put("下级外部机构人数列表", voList);
                } else if (key == 2) {
                    data.put("内部各部门人数列表", voList);
                }
            }
        }

        data.put("org", one);
        data.put("time", LocalDateTimeUtil.now());

        return Result.ok(data);
    }

    private void getDeptEmployeecurrentNum(List<Long> deptIds, List<DeptVO> deptTotalTree, HashMap<Long, Integer> countMap) {
        deptTotalTree.forEach(dept -> {
            if (deptIds.contains(dept.getDeptId())) {
                countMap.put(dept.getDeptId(), Integer.valueOf(dept.getTotalNum().toString()));
            }
            if (dept.getChildren() != null && CollectionUtils.isNotEmpty(dept.getChildren())) {
                getDeptEmployeecurrentNum(deptIds, dept.getChildren(), countMap);
            }
        });
    }

    @Override
    public Result getOrgSectorEmpNums(Integer orgSector, String kind, Integer type) {
        JSONObject data = new JSONObject();

        // 获取所有部门信息
        List<HrmDept> allDeptList = deptService.lambdaQuery().list();
        switch (type) {
            // 只统计合并报表企业人数
            case 1:
                allDeptList = allDeptList.stream().filter(dept -> type.equals(dept.getUnitProperties()) || dept.getDeptType() == 2).collect(Collectors.toList());
                break;
            // 统计合并报表企业与托管企业人数
            case 2:
                List<Integer> typeList = Arrays.asList(1,2);
                allDeptList = allDeptList.stream().filter(dept -> (dept.getUnitProperties() != null && typeList.contains(dept.getUnitProperties())) || dept.getDeptType() == 2).collect(Collectors.toList());
                break;
            // 统计所有人数
            default:
                break;
        }
        Map<Long, List<HrmDept>> allDeptMap = allDeptList.stream().collect(Collectors.groupingBy(HrmDept::getParentId));
        List<HrmDept> childDeptList = allDeptList.stream().filter(dept -> Objects.equals(orgSector, dept.getOrgSector())).collect(Collectors.toList());


        List<Long> deptIdList = new ArrayList<>();
        for (HrmDept dept : childDeptList){
            deptIdList.addAll(this.selectChildDeptListByDeptId(dept.getDeptId(), allDeptMap));

        }

        // 查询员工
        List<HrmEmployeeData> deptDataList = employeeDataService.lambdaQuery()
                .select(HrmEmployeeData::getFieldName, HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, HrmEmployeeData::getCreateTime)
                .eq(HrmEmployeeData::getFieldName, "dept")
                .list();

        Map<Long, String> deptOfEmpMap = deptDataList.stream()
                .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()) && deptIdList.contains(Long.valueOf(emp.getFieldValue())))
                .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
                .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
        List<Long> temporaryEmpIdList = deptOfEmpMap.keySet().stream().collect(Collectors.toList());

        List<HrmEmployee> allEmpList = employeeService.lambdaQuery()
                .select(HrmEmployee::getEmployeeId, HrmEmployee::getAge, HrmEmployee::getSex)
                .in(HrmEmployee::getEmployeeId, temporaryEmpIdList)
                .ne(HrmEmployee::getEntryStatus, 4)
                .eq(HrmEmployee::getIsDel, 0)
                .list();
        List<Long> empIdList = allEmpList.stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
        Map<String, Integer> deptOfCountEmp = deptOfEmpMap.entrySet().stream().filter((Map.Entry<Long, String> entry) -> empIdList.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getValue, v -> 1, Integer::sum));


        if (CollectionUtils.isNotEmpty(childDeptList)) {
            // 子集

            Map<Integer, List<HrmDept>> childDeptMap = childDeptList.stream().filter(dept -> dept.getDeptType() != null).collect(Collectors.groupingBy(HrmDept::getDeptType));
            Iterator<Map.Entry<Integer, List<HrmDept>>> childDeptIterator = childDeptMap.entrySet().iterator();

            while (childDeptIterator.hasNext()) {
                Map.Entry<Integer, List<HrmDept>> next = childDeptIterator.next();
                Integer key = next.getKey();
                if (key != 1 && key != 2) {
                    continue;
                }
                List<HrmDept> value = next.getValue();
                List<DeptEmployeeVO> voList = new ArrayList<>();
                value = value.stream().sorted(Comparator.comparing(HrmDept::getSortId, Comparator.nullsLast(Long::compareTo))).collect(Collectors.toList());
                for (int i = 0; i < value.size(); i++) {
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    HrmDept deptEmployeeVO = value.get(i);
                    List<HrmDept> deptByDeptId2 = this.getDeptByDeptId(deptEmployeeVO.getDeptId(), allDeptMap);
                    List<Long> deptIdList2 = deptByDeptId2.stream().map(dept -> dept.getDeptId()).collect(Collectors.toList());
                    deptIdList2.add(deptEmployeeVO.getDeptId());
                    int count = deptOfCountEmp.entrySet().stream().filter(entry -> deptIdList2.contains(Long.valueOf(entry.getKey()))).map(Map.Entry::getValue).mapToInt(Integer::intValue).sum();
                    BeanUtils.copyProperties(deptEmployeeVO, vo);
                    vo.setCurrentNum(count);
                    vo.setName(deptEmployeeVO.getName());
                    voList.add(vo);
                }
                data.put(key == 1? "下级外部机构人数列表":"内部各部门人数列表", voList);
            }
        }

        // 从业人员
        // 劳动合同工，劳务派遣，劳务外包与临时工（跟班学习算作临时工）
        Map<Long, String> workFormsMap = this.selectEmpDataMap(empIdList, "work_forms");
        List<String> workFormsList = Arrays.asList("劳动合同工","劳务派遣","劳务外包","临时工");
        Map<String, Integer> workFormsNumsMap = workFormsMap.entrySet().stream()
                .map(forms -> {
                    if("跟班学习".equals(forms.getValue())) {
                        forms.setValue("临时工");
                    }
                    return forms;
                })
                .filter(forms -> workFormsList.contains(forms))
                .collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));

//        Map<Long, String> highestDegreeMap = this.selectEmpDataMap(empIdList, "highest_degree");
//        Map<String, Integer> highestDegreeCountMap = highestDegreeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));
        Map<String, Integer> highestDegreeCountMap = allEmpList.stream().map(item -> {
            if (item.getHighestEducation() == null) {
                return "无";
            }
            return HrmHighestEducationEnum.parse(item.getHighestEducation()).getMsg();
        }).collect(Collectors.toMap(String::valueOf, el -> 1, Integer::sum));

        // 专技人才
        List<HrmEmployeeTechnical> technicalList = employeeTechnicalService.lambdaQuery()
                .select(HrmEmployeeTechnical::getEmployeeId, HrmEmployeeTechnical::getTechnicalLevel)
                .list();

        Map<String, Integer> technicalLevelMap = new HashMap<>();
        technicalLevelMap.put("正高级",1);
        technicalLevelMap.put("副高级",2);
        technicalLevelMap.put("员级",3);
        technicalLevelMap.put("中级",4);
        technicalLevelMap.put("初级",5);

        Map<String, Integer> collect = technicalList.stream()
                .filter(technical -> technical.getTechnicalLevel() != null
                        && technical.getEmployeeId() != null
                        && empIdList.contains(technical.getEmployeeId())
                        && technicalLevelMap.containsKey(technical.getTechnicalLevel()))
                .collect(Collectors.toMap(HrmEmployeeTechnical::getEmployeeId, v -> v, (v1, v2) ->
                        technicalLevelMap.get(v1.getTechnicalLevel()) > technicalLevelMap.get(v2.getTechnicalLevel()) ? v2 : v1
                )).entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toMap(HrmEmployeeTechnical::getTechnicalLevel, v -> 1, Integer::sum));


        List<String> workerStrList = Arrays.asList("初级工","中级工","高级工","技术","高级技术");
        List<HrmEmployeeSpecialWorker> workerList = employeeSpecialWorkerService.lambdaQuery()
                .select(HrmEmployeeSpecialWorker::getEmployeeId, HrmEmployeeSpecialWorker::getSpecialWorkerLevel, HrmEmployeeSpecialWorker::getCreateTime)
                .list();
        Map<Long, String> workerMap = workerList.stream()
                .filter(worker -> worker.getEmployeeId() != null && empIdList.contains(worker.getEmployeeId()) && workerStrList.contains(worker.getSpecialWorkerLevel()))
                .sorted(Comparator.comparing(HrmEmployeeSpecialWorker::getCreateTime))
                .collect(Collectors.toMap(HrmEmployeeSpecialWorker::getEmployeeId, HrmEmployeeSpecialWorker::getSpecialWorkerLevel, (e1, e2) -> e2));

        Map<String, Integer> workerCollect = workerMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));
        collect.putAll(workerCollect);

        List<Integer> ageList = allEmpList.stream().filter(emp -> emp.getAge() != null).map(HrmEmployee::getAge).collect(Collectors.toList());

        // 年龄结构
        Map<String, Long> ageMap = new HashMap<>();
        long thirtyFiveAge = ageList.stream().filter(age -> age <= 35).count();
        ageMap.put("35以下", thirtyFiveAge);
        long fortyAge = ageList.stream().filter(age -> age > 35 && age <= 40).count();
        ageMap.put("36-40", fortyAge);
        long fortyFiveAge = ageList.stream().filter(age -> age > 40 && age <= 45).count();
        ageMap.put("41-45", fortyFiveAge);
        long fiftyAge = ageList.stream().filter(age -> age > 45 && age <= 50).count();
        ageMap.put("46-50", fiftyAge);
        long fiftyFiveAge = ageList.stream().filter(age -> age > 50 && age <= 55).count();
        ageMap.put("51-54", fiftyFiveAge);
        long bigAge = ageList.stream().filter(age -> age > 55).count();
        ageMap.put("55以上", bigAge);

        HrmDept one = new HrmDept();
        one.setName(OrgSectorEnum.getNameByValue(orgSector));

        data.put("org", one);
        data.put("queryTypeName", OrgSectorEnum.getNameByValue(orgSector));
        data.put("time", LocalDateTimeUtil.now());
        data.put("专技人才", collect);
        data.put("从业人员", workFormsNumsMap);
        data.put("受教育程度", highestDegreeCountMap);
        data.put("年龄结构", ageMap);
        data.put("总人数", empIdList.size());

        return Result.ok(data);
    }

    @Override
    public Result getOrgEmpNums(Long qId, String kind, Integer type) {
        JSONObject data = new JSONObject();

        // 获取所有部门信息
        List<HrmDept> allDeptList = deptService.lambdaQuery().list();
        // 获取当前部门信息
        HrmDept one = allDeptList.stream().filter(dept -> qId == 0 ? qId.equals(dept.getParentId()) : qId.equals(dept.getDeptId())).findFirst().orElse(null);
        if (one == null) {
            return Result.ok();
        }
        switch (type) {
            // 只统计合并报表企业人数
            case 1:
                allDeptList = allDeptList.stream().filter(dept -> type.equals(dept.getUnitProperties()) || dept.getDeptType() == 2).collect(Collectors.toList());
                break;
            // 统计合并报表企业与托管企业人数
            case 2:
                List<Integer> typeList = Arrays.asList(1,2);
                allDeptList = allDeptList.stream().filter(dept -> (dept.getUnitProperties() != null && typeList.contains(dept.getUnitProperties())) || dept.getDeptType() == 2).collect(Collectors.toList());
                break;
            // 统计所有人数
            default:
                break;
        }
        Map<Long, List<HrmDept>> allDeptMap = allDeptList.stream().collect(Collectors.groupingBy(HrmDept::getParentId));
        List<Long> deptIdList = this.selectChildDeptListByDeptId(one.getDeptId(), allDeptMap);
        deptIdList.add(one.getDeptId());

        // 查询员工
        List<HrmEmployeeData> deptDataList = employeeDataService.lambdaQuery()
                .select(HrmEmployeeData::getFieldName, HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, HrmEmployeeData::getCreateTime)
                .eq(HrmEmployeeData::getFieldName, "dept")
                .list();

        Map<Long, String> deptOfEmpMap = deptDataList.stream()
                .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()) && deptIdList.contains(Long.valueOf(emp.getFieldValue())))
                .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
                .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
        List<Long> temporaryEmpIdList = deptOfEmpMap.keySet().stream().collect(Collectors.toList());

        List<HrmEmployee> allEmpList = employeeService.lambdaQuery()
                .select(HrmEmployee::getEmployeeId, HrmEmployee::getAge, HrmEmployee::getSex, HrmEmployee::getHighestEducation)
                .in(HrmEmployee::getEmployeeId, temporaryEmpIdList)
                .ne(HrmEmployee::getEntryStatus, 4)
                .eq(HrmEmployee::getIsDel, 0)
                .list();
        List<Long> empIdList = allEmpList.stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
        Map<String, Integer> deptOfCountEmp = deptOfEmpMap.entrySet().stream().filter((Map.Entry<Long, String> entry) -> empIdList.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getValue, v -> 1, Integer::sum));


        if (allDeptMap.containsKey(one.getDeptId())) {
            // 子集
            List<HrmDept> childDeptList = allDeptMap.get(one.getDeptId());

            Map<Integer, List<HrmDept>> childDeptMap = childDeptList.stream().filter(dept -> dept.getDeptType() != null).collect(Collectors.groupingBy(HrmDept::getDeptType));
            Iterator<Map.Entry<Integer, List<HrmDept>>> childDeptIterator = childDeptMap.entrySet().iterator();

            while (childDeptIterator.hasNext()) {
                Map.Entry<Integer, List<HrmDept>> next = childDeptIterator.next();
                Integer key = next.getKey();
                if (key != 1 && key != 2) {
                    continue;
                }
                List<HrmDept> value = next.getValue();
                List<DeptEmployeeVO> voList = new ArrayList<>();
                value = value.stream().sorted(Comparator.comparing(HrmDept::getSortId, Comparator.nullsLast(Long::compareTo))).collect(Collectors.toList());
                for (int i = 0; i < value.size(); i++) {
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    HrmDept deptEmployeeVO = value.get(i);
                    List<HrmDept> deptByDeptId2 = this.getDeptByDeptId(deptEmployeeVO.getDeptId(), allDeptMap);
                    List<Long> deptIdList2 = deptByDeptId2.stream().map(dept -> dept.getDeptId()).collect(Collectors.toList());
                    deptIdList2.add(deptEmployeeVO.getDeptId());
                    int count = deptOfCountEmp.entrySet().stream().filter(entry -> deptIdList2.contains(Long.valueOf(entry.getKey()))).map(Map.Entry::getValue).mapToInt(Integer::intValue).sum();
                    BeanUtils.copyProperties(deptEmployeeVO, vo);
                    vo.setCurrentNum(count);
                    vo.setName(deptEmployeeVO.getName());
                    voList.add(vo);
                }
                data.put(key == 1? "下级外部机构人数列表":"内部各部门人数列表", voList);
            }
        }

        // 分项统计
        if (qId == 0) {
            Map<String, Integer> map = new HashMap<>();
            Map<String, String> otNameMap = new HashMap<>();

            Map<Integer, String> orgSectorEnum = OrgSectorEnum.getOrgSectorEnum();
            Map<Integer, List<HrmDept>> otMap = allDeptList.stream().filter(dept -> orgSectorEnum.containsKey(dept.getOrgSector()) && one.getDeptId().equals(dept.getParentId())).collect(Collectors.groupingBy(HrmDept::getOrgSector));

            Iterator<Map.Entry<Integer, String>> orgSectorIterator = orgSectorEnum.entrySet().iterator();
            while (orgSectorIterator.hasNext()) {
                Map.Entry<Integer, String> next = orgSectorIterator.next();
                Integer key = next.getKey();
                String value = next.getValue();
                Integer sum = 0;
                if (otMap.containsKey(key)) {
                    List<HrmDept> deptList = otMap.get(key);
                    for (HrmDept dept : deptList) {
                        List<HrmDept> child = this.getDeptByDeptId(dept.getDeptId(), allDeptMap);
                        List<Long> childIdList = child.stream().map(info -> info.getDeptId()).collect(Collectors.toList());
                        childIdList.add(dept.getDeptId());
                        int count = deptOfCountEmp.entrySet().stream().filter(entry -> childIdList.contains(Long.valueOf(entry.getKey()))).map(Map.Entry::getValue).mapToInt(Integer::intValue).sum();
                        sum += count;
                    }
                }
                map.put("ot" + key, sum);
                otNameMap.put("ot" + key, value);
            }
            map.put("下属单位人数", empIdList.size());
            map.put("直属部门人数", 0);
            data.put("分项统计", map);
            data.put("otName", otNameMap);
        }

        // 从业人员
        // 劳动合同工，劳务派遣，劳务外包与临时工（跟班学习算作临时工）
        Map<Long, String> workFormsMap = this.selectEmpDataMap(empIdList, "work_forms");
        List<String> workFormsList = Arrays.asList("劳动合同工","劳务派遣","劳务外包","临时工");
        Map<String, Integer> workFormsNumsMap = workFormsMap.entrySet().stream()
                .map(forms -> {
                    if("跟班学习".equals(forms.getValue())) {
                        forms.setValue("临时工");
                    }
                    return forms;
                })
                .filter(forms -> workFormsList.contains(forms.getValue()))
                .collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));

//        Map<Long, String> highestDegreeMap = this.selectEmpDataMap(empIdList, "highest_degree");
//        Map<String, Integer> highestDegreeCountMap = highestDegreeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));
        Map<String, Integer> highestDegreeCountMap = allEmpList.stream().map(item -> {
            if (item.getHighestEducation() == null) {
                return "无";
            }
            return HrmHighestEducationEnum.parse(item.getHighestEducation()).getMsg();
        }).collect(Collectors.toMap(String::valueOf, el -> 1, Integer::sum));

        // 专技人才
        List<HrmEmployeeTechnical> technicalList = employeeTechnicalService.lambdaQuery()
                .select(HrmEmployeeTechnical::getEmployeeId, HrmEmployeeTechnical::getTechnicalLevel)
                .list();

        List<String> technicalStrMap = Arrays.asList("初级","中级","副高级","正高级");

        Map<String, Integer> technicalLevelMap = new HashMap<>();
        technicalLevelMap.put("正高级",1);
        technicalLevelMap.put("副高级",2);
        technicalLevelMap.put("员级",3);
        technicalLevelMap.put("中级",4);
        technicalLevelMap.put("初级",5);

        Map<String, Integer> collect = technicalList.stream()
                .filter(technical -> technical.getTechnicalLevel() != null
                        && technical.getEmployeeId() != null
                        && empIdList.contains(technical.getEmployeeId())
                        && technicalLevelMap.containsKey(technical.getTechnicalLevel()))
                .collect(Collectors.toMap(HrmEmployeeTechnical::getEmployeeId, v -> v, (v1, v2) ->
                        technicalLevelMap.get(v1.getTechnicalLevel()) > technicalLevelMap.get(v2.getTechnicalLevel()) ? v2 : v1
                )).entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toMap(HrmEmployeeTechnical::getTechnicalLevel, v -> 1, Integer::sum));


        List<HrmEmployeeSpecialWorker> workerList = employeeSpecialWorkerService.lambdaQuery()
                .select(HrmEmployeeSpecialWorker::getEmployeeId, HrmEmployeeSpecialWorker::getSpecialWorkerLevel, HrmEmployeeSpecialWorker::getCreateTime)
                .list();
        Map<Long, String> workerMap = workerList.stream()
                .filter(worker -> worker.getEmployeeId() != null && empIdList.contains(worker.getEmployeeId()) && !technicalStrMap.contains(worker.getSpecialWorkerLevel()))
                .sorted(Comparator.comparing(HrmEmployeeSpecialWorker::getCreateTime))
                .collect(Collectors.toMap(HrmEmployeeSpecialWorker::getEmployeeId, HrmEmployeeSpecialWorker::getSpecialWorkerLevel, (e1, e2) -> e2));

        Map<String, Integer> workerCollect = workerMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, el -> 1, Integer::sum));
        collect.putAll(workerCollect);

        List<Integer> ageList = allEmpList.stream().filter(emp -> emp.getAge() != null).map(HrmEmployee::getAge).collect(Collectors.toList());
        // 年龄结构
        Map<String, Long> ageMap = new HashMap<>();
        long thirtyFiveAge = ageList.stream().filter(age -> age <= 35).count();
        ageMap.put("35以下", thirtyFiveAge);
        long fortyAge = ageList.stream().filter(age -> age > 35 && age <= 40).count();
        ageMap.put("36-40", fortyAge);
        long fortyFiveAge = ageList.stream().filter(age -> age > 40 && age <= 45).count();
        ageMap.put("41-45", fortyFiveAge);
        long fiftyAge = ageList.stream().filter(age -> age > 45 && age <= 50).count();
        ageMap.put("46-50", fiftyAge);
        long fiftyFiveAge = ageList.stream().filter(age -> age > 50 && age <= 55).count();
        ageMap.put("51-54", fiftyFiveAge);
        long bigAge = ageList.stream().filter(age -> age > 55).count();
        ageMap.put("55以上", bigAge);

        data.put("org", one);
        data.put("queryTypeName", one.getName());
        data.put("time", LocalDateTimeUtil.now());
        data.put("专技人才", collect);
        data.put("从业人员", workFormsNumsMap);
        data.put("受教育程度", highestDegreeCountMap);
        data.put("年龄结构", ageMap);
        data.put("总人数", empIdList.size());

        return Result.ok(data);
    }


    /**
     * 获取自定义字段
     *
     * @param employeeIdList
     * @return
     */
    public Map<Long, String> selectEmpDataMap(List<Long> employeeIdList, String vla) {
        if (CollectionUtils.isEmpty(employeeIdList)) {
            return new HashMap<>();
        }

        List<HrmEmployeeData> highestDegreeList;

        if (employeeIdList.size() > 10000) {
            highestDegreeList = employeeDataService.lambdaQuery()
                    .select(HrmEmployeeData::getFieldName, HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, HrmEmployeeData::getCreateTime)
                    .eq(HrmEmployeeData::getFieldName, vla)
                    .list();
        } else {
            highestDegreeList = employeeDataService.lambdaQuery()
                    .select(HrmEmployeeData::getFieldName, HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, HrmEmployeeData::getCreateTime)
                    .eq(HrmEmployeeData::getFieldName, vla)
                    .in(HrmEmployeeData::getEmployeeId, employeeIdList)
                    .list();
        }
        Map<Long, String> map;
        if (employeeIdList.size() > 10000) {
            map = highestDegreeList.stream()
                    .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()) && employeeIdList.contains(emp.getEmployeeId()))
                    .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
                    .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
        } else {
            map = highestDegreeList.stream()
                    .filter(emp -> emp.getEmployeeId() != null && StringUtils.isNotEmpty(emp.getFieldValue()))
                    .sorted(Comparator.comparing(HrmEmployeeData::getCreateTime))
                    .collect(Collectors.toMap(HrmEmployeeData::getEmployeeId, HrmEmployeeData::getFieldValue, (e1, e2) -> e2));
        }

        return map;
    }

    /**
     * 查询子级机构
     *
     * @param deptId
     * @param map
     * @return
     */
    public List<Long> selectChildDeptListByDeptId(Long deptId, Map<Long, List<HrmDept>> map) {
        List<Long> list = new ArrayList<>();
        if (!map.containsKey(deptId)) {
            return list;
        }

        List<HrmDept> deptList = map.get(deptId);
        for (int i = 0; i < deptList.size(); i++) {
            HrmDept dept = deptList.get(i);
            if (map.containsKey(deptId)) {
                List<Long> deptIdList = this.selectChildDeptListByDeptId(dept.getDeptId(), map);
                list.addAll(deptIdList);
            }
        }
        List<Long> deptIdList = deptList.stream().map(HrmDept::getDeptId).collect(Collectors.toList());
        list.addAll(deptIdList);
        return list;
    }

    /**
     * 查询机构下的员工
     *
     * @param deptId
     * @param map
     * @return
     */
    public List<HrmDept> getDeptByDeptId(Long deptId, Map<Long, List<HrmDept>> map) {
        List<HrmDept> list = new ArrayList<>();
        if (!map.containsKey(deptId)) {
            return new ArrayList<>();
        }

        List<HrmDept> deptEmployeeVOS = map.get(deptId);
        for (int i = 0; i < deptEmployeeVOS.size(); i++) {
            HrmDept deptEmployeeVO = deptEmployeeVOS.get(i);
            if (map.containsKey(deptId)) {
                List<HrmDept> deptByDeptId = this.getDeptByDeptId(deptEmployeeVO.getDeptId(), map);
                list.addAll(deptByDeptId);
            }
        }
        list.addAll(deptEmployeeVOS);
        return list;
    }


    @Override
    public Result workbenchTotal(Long deptId, String totalType, Integer type, Integer dimension) {
        JSONObject data = new JSONObject();
        data.put("部门人数统计",new ArrayList<>());
        // 获取所有部门信息
        List<HrmDept> allDeptList = deptService.lambdaQuery().list();
        // 部门分组
        Map<Long, List<HrmDept>> deptGroup = allDeptList.stream().collect(Collectors.groupingBy(HrmDept::getParentId));
        List<HrmDept> hrmDepts = deptGroup.get(OrgConstant.TOP_ORG_ID);
        //所有人员
        List<HrmEmployee> allEmpList = employeeService.queryWorkbenchTotal();
        //机构集合
        List<HrmDept> orgList = new ArrayList<>();
        //设置所有部门单位性质和部门板块
        if (hrmDepts != null && !hrmDepts.isEmpty()) {
            for (HrmDept hrmDept : hrmDepts) {
                orgList.add(hrmDept);
                setChildDeptUnitProperties(deptGroup.get(hrmDept.getDeptId()), deptGroup, hrmDept.getUnitProperties(), hrmDept.getOrgSector(), orgList);
            }
        }
        if (dimension == 1) {
            switch (type) {
                // 只统计合并报表企业人数
                case 1:
                    allDeptList = allDeptList.stream().filter(dept -> type.equals(dept.getUnitProperties())).collect(Collectors.toList());
                    break;
                // 统计合并报表企业与托管企业人数
                case 2:
                    List<Integer> typeList = Arrays.asList(1, 2);
                    allDeptList = allDeptList.stream().filter(dept -> typeList.contains(dept.getUnitProperties())).collect(Collectors.toList());
                    break;
                // 统计所有人数
                default:
                    break;
            }
            if (WorkbenchTotalTypeEnum.ORGSECTOR.getValue().equals(totalType)) {
                if (type != 3){
                    //人员统计
                    ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                    //人员部门分组
                    Map<Long, List<HrmEmployee>> empGroup = allEmpList.stream().collect(Collectors.groupingBy(HrmEmployee::getDeptId));

                    for (HrmDept hrmDept : allDeptList) {
                        List<HrmEmployee> hrmEmployeeList = empGroup.get(hrmDept.getDeptId());
                        if (hrmEmployeeList == null || hrmEmployeeList.isEmpty()){
                            continue;
                        }
                        hrmEmployees.addAll(hrmEmployeeList);
                    }
                    allEmpList = hrmEmployees;
                }
                // 机构板块统计
                Map<Integer, List<HrmDept>> orgDeptMap = allDeptList.stream().filter(dept -> dept.getParentId() != 0L && dept.getOrgSector() != null).collect(Collectors.groupingBy(HrmDept::getOrgSector));
                OrgSectorEnum[] values = OrgSectorEnum.values();
                List<DeptEmployeeVO> voList = new ArrayList<>();
                for (OrgSectorEnum orgSectorEnum : values) {
                    List<HrmDept> deptList = orgDeptMap.get(orgSectorEnum.getValue());
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    vo.setDeptType(2);
                    vo.setKind(WorkbenchTotalTypeEnum.ORG.getValue());
                    vo.setName(orgSectorEnum.getName());
                    vo.setDeptId(Long.valueOf(orgSectorEnum.getValue()));
                    if (deptList == null || deptList.isEmpty()) {
                        vo.setCurrentNum(0);
                    } else {
                        Map<Long, HrmDept> hrmDeptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity(), (e1, e2) -> e2));
                        long count = allEmpList.stream().filter(employee -> hrmDeptMap.containsKey(employee.getDeptId())).count();
                        vo.setCurrentNum((int) count);
                    }
                    voList.add(vo);
                }
                data.put("部门人数统计", voList);
            } else if (WorkbenchTotalTypeEnum.ORG.getValue().equals(totalType)) {
                // 机构统计
                List<HrmDept> deptList = hrmDepts.stream().filter(dept -> dept.getOrgSector() != null && dept.getOrgSector() == Integer.parseInt(String.valueOf(deptId))).collect(Collectors.toList());
                //人员部门分组
                Map<Long, List<HrmEmployee>> empGroup = allEmpList.stream().collect(Collectors.groupingBy(HrmEmployee::getDeptId));
                //人员统计
                ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                List<DeptEmployeeVO> voList = new ArrayList<>();
                if (!deptList.isEmpty()) {
                    for (HrmDept hrmDept : deptList) {
                        //递归获取部门下的所有员工
                        List<HrmEmployee> hrmDeptList = new ArrayList<>();
                        getChildDeptUserList(hrmDept.getDeptId(), deptGroup, empGroup, hrmDeptList);
                        hrmEmployees.addAll(hrmDeptList);
                        DeptEmployeeVO vo = new DeptEmployeeVO();
                        vo.setDeptType(hrmDept.getDeptType());
                        vo.setKind(WorkbenchTotalTypeEnum.DEPT.getValue());
                        vo.setName(hrmDept.getName());
                        vo.setCurrentNum(hrmDeptList.size());
                        vo.setDeptId(hrmDept.getDeptId());
                        voList.add(vo);
                    }
                    data.put("部门人数统计", voList);
                }
                allEmpList = hrmEmployees;
            } else {
                //人员统计
                ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                // 部门统计
                List<HrmDept> deptRoot = deptGroup.get(deptId);
                //人员部门分组
                Map<Long, List<HrmEmployee>> empGroup = allEmpList.stream().collect(Collectors.groupingBy(HrmEmployee::getDeptId));
                List<DeptEmployeeVO> voList = new ArrayList<>();
                if (deptRoot != null && !deptRoot.isEmpty()) {
                    for (HrmDept hrmDept : deptRoot) {
                        //递归获取部门下的所有员工
                        List<HrmEmployee> hrmDeptList = new ArrayList<>();
                        getChildDeptUserList(hrmDept.getDeptId(), deptGroup, empGroup, hrmDeptList);
                        hrmEmployees.addAll(hrmDeptList);
                        DeptEmployeeVO vo = new DeptEmployeeVO();
                        vo.setDeptType(hrmDept.getDeptType());
                        vo.setKind(WorkbenchTotalTypeEnum.DEPT.getValue());
                        vo.setName(hrmDept.getName());
                        vo.setCurrentNum(hrmDeptList.size());
                        vo.setDeptId(hrmDept.getDeptId());
                        voList.add(vo);
                    }
                } else {
                    Map<Long, HrmDept> deptMap = allDeptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity(), (e1, e2) -> e2));
                    HrmDept hrmDept = deptMap.get(deptId);
                    List<HrmEmployee> employeeList = Optional.ofNullable(empGroup.get(deptId)).orElse(new ArrayList<>());
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    vo.setDeptType(hrmDept.getDeptType());
                    vo.setName(hrmDept.getName());
                    vo.setCurrentNum(employeeList.size());
                    vo.setDeptId(hrmDept.getDeptId());
                    vo.setKind(WorkbenchTotalTypeEnum.NOCHILDREN.getValue());
                    voList.add(vo);
                    hrmEmployees.addAll(employeeList);
                }
                data.put("部门人数统计", voList);
                allEmpList = hrmEmployees;
            }
        }else {
            List<DeptEmployeeVO> voList = new ArrayList<>();
            if (type == 3) {
                //企业类别
                Map<Integer, List<HrmDept>> orgDeptMap = orgList.stream().filter(item -> item.getOrgSector() != null).collect(Collectors.groupingBy(HrmDept::getOrgSector));
                OrgSectorEnum[] values = OrgSectorEnum.values();
                for (OrgSectorEnum orgSectorEnum : values) {
                    List<HrmDept> deptList = orgDeptMap.get(orgSectorEnum.getValue());
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    vo.setKind(WorkbenchTotalTypeEnum.NOCHILDREN.getValue());
                    vo.setName(orgSectorEnum.getName());
                    vo.setDeptId(Long.valueOf(orgSectorEnum.getValue()));
                    vo.setCurrentNum(deptList != null ? deptList.size() : 0);
                    voList.add(vo);
                }
            } else if (type == 1) {
                //单位分级
                Map<Integer, List<HrmDept>> deptLevelGroup = orgList.stream().collect(Collectors.groupingBy(HrmDept::getLevel));
                deptLevelGroup.keySet().stream().sorted(Comparator.comparing(Integer::intValue)).forEach(level -> {
                    List<HrmDept> deptList = deptLevelGroup.get(level);
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    vo.setKind(WorkbenchTotalTypeEnum.NOCHILDREN.getValue());
                    vo.setName("第" + (level - 1)  + "级单位");
                    vo.setDeptId(Long.valueOf(level));
                    vo.setCurrentNum(deptList.size());
                    voList.add(vo);
                });
            } else if (type == 2) {
                //报表及托管
                Map<Integer, List<HrmDept>> deptUnitGroup = orgList.stream().collect(Collectors.groupingBy(HrmDept::getUnitProperties));
                UnitPropertiesEnum[] values = UnitPropertiesEnum.values();
                for (UnitPropertiesEnum unitPropertiesEnum : values) {
                    List<HrmDept> deptList = deptUnitGroup.get(unitPropertiesEnum.getValue());
                    DeptEmployeeVO vo = new DeptEmployeeVO();
                    vo.setKind(WorkbenchTotalTypeEnum.NOCHILDREN.getValue());
                    vo.setName(unitPropertiesEnum.getName());
                    vo.setDeptId(Long.valueOf(unitPropertiesEnum.getValue()));
                    vo.setCurrentNum(deptList != null ? deptList.size() : 0);
                    voList.add(vo);
                }
            }
            data.put("部门人数统计", voList);
        }
        // 总人数
        List<Long> empIdList = allEmpList.stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
        empIdList.add(-1L);
        // 从业人员期末人数统计
        List<String> workFormsList = Arrays.asList("劳动合同工","劳务派遣","劳务外包","临时工","退休返聘","外部董事");
        Map<String, Integer> workFormsNumsMap = new HashMap<>();
        List<HrmEmployee> finalAllEmpList = allEmpList;
        workFormsList.forEach(workForms -> {
            long count = finalAllEmpList.stream().filter(employee -> workForms.equals(employee.getWorkForms())).count();
            workFormsNumsMap.put(workForms, (int) count);
        });
        //年龄层次
        List<Integer> ageList = allEmpList.stream().filter(emp -> emp.getAge() != null).map(HrmEmployee::getAge).collect(Collectors.toList());
        // 年龄结构
        Map<String, Long> ageMap = new HashMap<>();
        long thirtyFiveAge = ageList.stream().filter(age -> age <= 35).count();
        ageMap.put("35以下", thirtyFiveAge);
        long fortyAge = ageList.stream().filter(age -> age > 35 && age <= 40).count();
        ageMap.put("36-40", fortyAge);
        long fortyFiveAge = ageList.stream().filter(age -> age > 40 && age <= 45).count();
        ageMap.put("41-45", fortyFiveAge);
        long fiftyAge = ageList.stream().filter(age -> age > 45 && age <= 50).count();
        ageMap.put("46-50", fiftyAge);
        long fiftyFiveAge = ageList.stream().filter(age -> age > 50 && age <= 55).count();
        ageMap.put("51-55", fiftyFiveAge);
        long bigAge = ageList.stream().filter(age -> age > 55).count();
        ageMap.put("55以上", bigAge);
        //学历层次
        Map<String, Integer> highestDegreeCountMap = allEmpList.stream().map(item -> {
            if (item.getHighestEducation() == null) {
                return "无";
            }
            return HrmHighestEducationEnum.parse(item.getHighestEducation()).getMsg();
        }).collect(Collectors.toMap(String::valueOf, el -> 1, Integer::sum));
        //专业技术
        List<HrmEmployeeTechnical> technicalEmpList = employeeTechnicalService.lambdaQuery()
                .select(HrmEmployeeTechnical::getEmployeeId, HrmEmployeeTechnical::getTechnicalLevel)
                .in(HrmEmployeeTechnical::getEmployeeId, empIdList)
                .list();
        List<String> technicalList = Arrays.asList("初级","中级","副高级","正高级");
        Map<String, Integer> technicalNumsMap = new HashMap<>();
        technicalList.forEach(technical -> {
            List<HrmEmployeeTechnical> collect = technicalEmpList.stream().filter(emp -> technical.equals(emp.getTechnicalLevel())).collect(Collectors.toList());
            long count = collect.stream().map(HrmEmployeeTechnical::getEmployeeId).distinct().count();
            technicalNumsMap.put(technical, (int) count);
        });
        // 技能人才
        List<HrmEmployeeSpecialWorker> workerEmpList = employeeSpecialWorkerService.lambdaQuery()
                .select(HrmEmployeeSpecialWorker::getEmployeeId, HrmEmployeeSpecialWorker::getSpecialWorkerLevel, HrmEmployeeSpecialWorker::getCreateTime)
                .in(HrmEmployeeSpecialWorker::getEmployeeId, empIdList)
                .list();
        List<String> workerList = Arrays.asList("初级工","中级工","高级工","技师","高级技师");
        Map<String, Integer> workerNumsMap = new HashMap<>();
        workerList.forEach(technical -> {
            List<HrmEmployeeSpecialWorker> collect = workerEmpList.stream().filter(emp -> technical.equals(emp.getSpecialWorkerLevel())).collect(Collectors.toList());
            long count = collect.stream().map(HrmEmployeeSpecialWorker::getEmployeeId).distinct().count();
            workerNumsMap.put(technical, (int) count);
        });

        data.put("技能人才", workerNumsMap);
        data.put("专技人才", technicalNumsMap);
        data.put("从业人员", workFormsNumsMap);
        data.put("年龄结构", ageMap);
        data.put("受教育程度", highestDegreeCountMap);
        data.put("总人数", dimension == 1 ? empIdList.size() - 1 : orgList.size());
        return Result.ok(data);
    }

    private void getChildDeptUserList(Long deptId, Map<Long, List<HrmDept>> deptGroup, Map<Long, List<HrmEmployee>> empGroup,List<HrmEmployee> hrmEmployeeList) {
        List<HrmDept> hrmDepts = deptGroup.get(deptId);
        List<HrmEmployee> employeeList = empGroup.get(deptId);
        if (employeeList != null && !employeeList.isEmpty()) {
            hrmEmployeeList.addAll(employeeList);
        }
        if (hrmDepts != null) {
            for (HrmDept hrmDept : hrmDepts) {
                getChildDeptUserList(hrmDept.getDeptId(),deptGroup,empGroup, hrmEmployeeList);
            }
        }
    }

    private void setChildDeptUnitProperties(List<HrmDept> hrmDepts, Map<Long, List<HrmDept>> deptGroup, Integer unitProperties, Integer orgSector, List<HrmDept> orgList) {
        if (hrmDepts != null) {
            for (HrmDept hrmDept : hrmDepts) {
                if (hrmDept.getDeptType() == 2){
                    hrmDept.setUnitProperties(unitProperties);
                    hrmDept.setOrgSector(orgSector);
                    setChildDeptUnitProperties(deptGroup.get(hrmDept.getDeptId()), deptGroup, unitProperties, orgSector, orgList);
                }else {
                    Integer unit = unitProperties;
                    Integer org = orgSector;
                    if (hrmDept.getUnitProperties() != null){
                        unit = hrmDept.getUnitProperties();
                    }
                    if (hrmDept.getOrgSector() != null){
                        org = hrmDept.getOrgSector();
                    }
                    hrmDept.setUnitProperties(unit);
                    hrmDept.setOrgSector(org);
                    orgList.add(hrmDept);
                    setChildDeptUnitProperties(deptGroup.get(hrmDept.getDeptId()), deptGroup, unit, org, orgList);
                }
            }
        }
    }

    @Override
    public BasePage<Map<String, Object>> queryWorkbenchPageEmployeeList(QueryWorkbenchEmployeeListBO employeeListBO) {
        //所有人员
        List<HrmEmployee> allEmpList = employeeService.queryWorkbenchTotal();
        // 获取所有部门信息
        List<HrmDept> allDeptList = deptService.lambdaQuery().list();
        Map<Long, HrmDept> deptMap = new HashMap<>();
        if (allDeptList != null && !allDeptList.isEmpty()){
            deptMap = allDeptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity()));
        }
        // 人员统计
        if (employeeListBO.getDimension() == 1){
            // 部门分组
            Map<Long, List<HrmDept>> deptGroup = allDeptList.stream().collect(Collectors.groupingBy(HrmDept::getParentId));
            //人员部门分组
            Map<Long, List<HrmEmployee>> empGroup = allEmpList.stream().collect(Collectors.groupingBy(HrmEmployee::getDeptId));
            switch (employeeListBO.getType()) {
                // 只统计合并报表企业人数
                case 1:
                    allDeptList = allDeptList.stream().filter(dept -> employeeListBO.getType().equals(dept.getUnitProperties())).collect(Collectors.toList());
                    break;
                // 统计合并报表企业与托管企业人数
                case 2:
                    List<Integer> typeList = Arrays.asList(1, 2);
                    allDeptList = allDeptList.stream().filter(dept -> typeList.contains(dept.getUnitProperties())).collect(Collectors.toList());
                    break;
                // 统计所有人数
                default:
                    break;
            }
            if (WorkbenchTotalTypeEnum.ORGSECTOR.getValue().equals(employeeListBO.getTotalType())) {
                //人员统计
                ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                for (HrmDept hrmDept : allDeptList) {
                    List<HrmEmployee> hrmEmployeeList = empGroup.get(hrmDept.getDeptId());
                    if (hrmEmployeeList == null || hrmEmployeeList.isEmpty()){
                        continue;
                    }
                    hrmEmployees.addAll(hrmEmployeeList);
                }
                allEmpList = hrmEmployees;
            } else if (WorkbenchTotalTypeEnum.ORG.getValue().equals(employeeListBO.getTotalType())) {
                // 机构统计
                List<HrmDept> hrmDepts = deptGroup.get(OrgConstant.TOP_ORG_ID);
                List<HrmDept> deptList = hrmDepts.stream().filter(dept -> dept.getOrgSector() != null && dept.getOrgSector() == Integer.parseInt(String.valueOf(employeeListBO.getDeptId()))).collect(Collectors.toList());
                //人员统计
                ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                if (!deptList.isEmpty()) {
                    for (HrmDept hrmDept : deptList) {
                        //递归获取部门下的所有员工
                        List<HrmEmployee> hrmDeptList = new ArrayList<>();
                        getChildDeptUserList(hrmDept.getDeptId(), deptGroup, empGroup, hrmDeptList);
                        hrmEmployees.addAll(hrmDeptList);
                    }
                }
                allEmpList = hrmEmployees;
            } else {
                //人员统计
                ArrayList<HrmEmployee> hrmEmployees = new ArrayList<>();
                // 部门统计
                List<HrmDept> deptRoot = deptGroup.get(employeeListBO.getDeptId());
                if (deptRoot != null && !deptRoot.isEmpty()) {
                    for (HrmDept hrmDept : deptRoot) {
                        //递归获取部门下的所有员工
                        List<HrmEmployee> hrmDeptList = new ArrayList<>();
                        getChildDeptUserList(hrmDept.getDeptId(), deptGroup, empGroup, hrmDeptList);
                        hrmEmployees.addAll(hrmDeptList);
                    }
                } else {
                    List<HrmEmployee> employeeList = Optional.ofNullable(empGroup.get(employeeListBO.getDeptId())).orElse(new ArrayList<>());
                    hrmEmployees.addAll(employeeList);
                }
                allEmpList = hrmEmployees;
            }

        }
        // 总人数
        List<Long> empIdList = allEmpList.stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
        empIdList.add(-1L);

        BasePage<Map<String, Object>> employeePage = employeeMapper.queryWorkbenchPageEmployeeList(employeeListBO.parse(), employeeListBO, empIdList);

        List<Map<String, Object>> list = employeePage.getList();
        if (list != null && !list.isEmpty()){
            // 获取员工自定义字段
            List<Long> empIds = list.stream().map(map -> Long.valueOf(map.get("employeeId").toString())).collect(Collectors.toList());
            List<HrmEmployeeData> employeeDataList = employeeDataService.lambdaQuery().in(HrmEmployeeData::getEmployeeId, empIds).list();
            Map<Long, List<HrmEmployeeData>> employeeDataGroup = employeeDataList.stream().collect(Collectors.groupingBy(HrmEmployeeData::getEmployeeId));
            // 获取脱敏字段
            Map<Integer, List<String>> encryptFieldGroup = employeeEncryptFieldService.fieldListGroupByType();

            for (Map<String, Object> empMap : list) {
                Long empId = Long.valueOf(empMap.get("employeeId").toString());
                if (employeeDataGroup.containsKey(empId)) {
                    List<HrmEmployeeData> fieldList= employeeDataGroup.get(empId);
                    for (int i = 0; i < fieldList.size(); i++) {
                        empMap.put(StrUtil.toCamelCase(fieldList.get(i).getFieldName()), fieldList.get(i).getFieldValue());
                    }
                }
                HrmDept dept = deptMap.get(Optional.ofNullable(empMap.get("deptId")).map(Object::toString).map(Long::valueOf).orElse(0L));
                if (dept != null){
                    empMap.put("dept", dept.getName());
                }else {
                    empMap.put("dept", "");
                }
                HrmDept org = deptMap.get(Optional.ofNullable(empMap.get("orgId")).map(Object::toString).map(Long::valueOf).orElse(0L));
                if (org != null){
                    empMap.put("org", org.getName());
                }else {
                    empMap.put("org", "");
                }
                List<String> encryptFieldList = encryptFieldGroup.get(EmployeeEncryptFieldTypeEnum.LIST.getValue());
                if (encryptFieldList != null && !encryptFieldList.isEmpty()){
                    encryptFieldList.forEach(field -> {
                        empMap.put(field, "******");
                    });
                }
            }
        }
        return employeePage;
    }
}
